<template>
  <div 
    class="markdown-content prose prose-gray dark:prose-invert max-w-none"
    v-html="renderedHtml"
  ></div>
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, watch } from 'vue'
import MarkdownIt from 'markdown-it'
import hljs from 'highlight.js'
import 'highlight.js/styles/github-dark.css'

interface Props {
  content: string
}

const props = defineProps<Props>()

// 创建markdown-it实例
const md = new MarkdownIt({
  html: true,        // 启用HTML标签
  xhtmlOut: false,   // 使用 '>' 来关闭单标签
  breaks: true,      // 转换段落里的 '\n' 到 <br>
  langPrefix: 'language-',  // 给围栏代码块的CSS语言前缀
  linkify: true,     // 将类似URL的文本自动转换为链接
  typographer: true, // 启用一些语言中性的替换 + 引号美化
  quotes: '""\'\'',
  
  // 代码高亮函数
  highlight: function (str: string, lang: string) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return '<pre class="hljs"><code>' +
               hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
               '</code></pre>'
      } catch (__) {}
    }

    return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>'
  }
})

// 自定义渲染规则
const defaultRender = md.renderer.rules.fence || function(tokens, idx, options, env, renderer) {
  return renderer.renderToken(tokens, idx, options)
}

// 自定义代码块渲染
md.renderer.rules.fence = function (tokens, idx, options, env, renderer) {
  const token = tokens[idx]
  const info = token.info ? md.utils.unescapeAll(token.info).trim() : ''
  let langName = ''
  
  if (info) {
    langName = info.split(/\s+/g)[0]
  }

  const langClass = langName ? ` language-${langName}` : ''
  const langDisplay = langName || 'text'
  
  let highlighted = ''
  if (langName && hljs.getLanguage(langName)) {
    try {
      highlighted = hljs.highlight(token.content, { 
        language: langName,
        ignoreIllegals: true 
      }).value
    } catch (err) {
      console.warn('代码高亮失败:', err)
      highlighted = md.utils.escapeHtml(token.content)
    }
  } else {
    highlighted = md.utils.escapeHtml(token.content)
  }

  return `
    <div class="code-block-container my-6 rounded-lg overflow-hidden border border-gray-200 dark:border-gray-700 shadow-sm">
      <div class="code-block-header bg-gray-50 dark:bg-gray-800 px-4 py-3 flex items-center justify-between border-b border-gray-200 dark:border-gray-700">
        <span class="text-sm font-mono text-gray-600 dark:text-gray-400">${langDisplay}</span>
        <button 
          onclick="copyCodeToClipboard(this)" 
          class="copy-btn flex items-center gap-2 px-3 py-1 text-xs bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded transition-colors"
          title="复制代码"
        >
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path>
          </svg>
          <span>复制</span>
        </button>
      </div>
      <pre class="code-block-content bg-gray-900 dark:bg-gray-950 p-4 overflow-x-auto text-sm"><code class="hljs${langClass}">${highlighted}</code></pre>
    </div>
  `
}

// 自定义标题渲染，添加锚点
md.renderer.rules.heading_open = function (tokens, idx, options, env, renderer) {
  const token = tokens[idx]
  const level = token.tag.slice(1) // h1 -> 1, h2 -> 2, etc.
  const nextToken = tokens[idx + 1]
  
  if (nextToken && nextToken.type === 'inline') {
    const content = nextToken.content
    const anchor = content
      .toLowerCase()
      .replace(/[^\w\u4e00-\u9fa5\s-]/g, '')
      .replace(/\s+/g, '-')
      .replace(/-+/g, '-')
      .replace(/^-|-$/g, '')
    
    const anchorId = anchor || `heading-${level}-${Date.now()}`
    
    return `<${token.tag} id="${anchorId}" class="group relative">`
  }
  
  return `<${token.tag}>`
}

// 自定义表格渲染
md.renderer.rules.table_open = function () {
  return '<div class="table-wrapper my-6 overflow-x-auto rounded-lg border border-gray-200 dark:border-gray-700">\n<table class="w-full border-collapse bg-white dark:bg-gray-800">\n'
}

md.renderer.rules.table_close = function () {
  return '</table>\n</div>\n'
}

md.renderer.rules.thead_open = function () {
  return '<thead class="bg-gray-50 dark:bg-gray-700">\n'
}

md.renderer.rules.tbody_open = function () {
  return '<tbody>\n'
}

md.renderer.rules.tr_open = function (tokens, idx) {
  const token = tokens[idx]
  const isHeader = token.attrGet('style') === 'header'
  return isHeader 
    ? '<tr>\n' 
    : '<tr class="border-b border-gray-200 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors">\n'
}

md.renderer.rules.th_open = function (tokens, idx) {
  return '<th class="px-4 py-3 text-left font-semibold text-gray-900 dark:text-gray-100">'
}

md.renderer.rules.td_open = function (tokens, idx) {
  return '<td class="px-4 py-3 text-gray-700 dark:text-gray-300">'
}

// 渲染Markdown内容
const renderedHtml = computed(() => {
  const content = props.content || ''
  
  if (!content.trim()) {
    return '<div class="text-gray-500 dark:text-gray-400 italic text-center py-12">开始编写您的 Markdown 文档...</div>'
  }
  
  try {
    const result = md.render(content)
    return result
  } catch (error) {
    console.error('Markdown渲染错误:', error)
    return `
      <div class="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4 my-4">
        <h4 class="text-red-800 dark:text-red-200 font-semibold mb-2">Markdown 渲染错误</h4>
        <p class="text-red-600 dark:text-red-300 text-sm">${error instanceof Error ? error.message : '未知错误'}</p>
        <details class="mt-2">
          <summary class="cursor-pointer text-sm">查看原始内容</summary>
          <pre class="mt-2 text-xs bg-red-100 dark:bg-red-900/40 p-2 rounded overflow-auto whitespace-pre-wrap">${content}</pre>
        </details>
      </div>
    `
  }
})

// 全局复制代码功能
const setupCopyFunction = () => {
  if (typeof window !== 'undefined') {
    (window as any).copyCodeToClipboard = async function(button: HTMLButtonElement) {
      const codeBlock = button.closest('.code-block-container')?.querySelector('.code-block-content code')
      if (codeBlock) {
        const text = codeBlock.textContent || ''
        try {
          await navigator.clipboard.writeText(text)
          
          // 更新按钮状态
          const span = button.querySelector('span')
          const originalText = span?.textContent
          if (span) {
            span.textContent = '已复制!'
            button.classList.add('text-green-600', 'dark:text-green-400')
            
            setTimeout(() => {
              span.textContent = originalText
              button.classList.remove('text-green-600', 'dark:text-green-400')
            }, 2000)
          }
        } catch (err) {
          console.error('复制失败:', err)
          const span = button.querySelector('span')
          if (span) {
            span.textContent = '复制失败'
            setTimeout(() => {
              span.textContent = '复制'
            }, 2000)
          }
        }
      }
    }
  }
}

onMounted(() => {
  setupCopyFunction()
})

// 监听内容变化，重新设置复制功能
watch(() => props.content, () => {
  nextTick(() => {
    setupCopyFunction()
  })
})
</script>

<style scoped>
/* 自定义prose样式 */
.markdown-content {
  @apply text-gray-800 dark:text-gray-200;
}

/* 标题样式 */
.markdown-content :deep(h1) {
  @apply text-3xl font-bold text-gray-900 dark:text-gray-100 mt-8 mb-6 border-b-2 border-gray-200 dark:border-gray-700 pb-3;
}

.markdown-content :deep(h2) {
  @apply text-2xl font-semibold text-gray-900 dark:text-gray-100 mt-6 mb-4 border-b border-gray-200 dark:border-gray-700 pb-2;
}

.markdown-content :deep(h3) {
  @apply text-xl font-semibold text-gray-900 dark:text-gray-100 mt-6 mb-4;
}

.markdown-content :deep(h4) {
  @apply text-lg font-semibold text-gray-900 dark:text-gray-100 mt-4 mb-3;
}

.markdown-content :deep(h5) {
  @apply text-base font-semibold text-gray-900 dark:text-gray-100 mt-4 mb-3;
}

.markdown-content :deep(h6) {
  @apply text-sm font-semibold text-gray-900 dark:text-gray-100 mt-4 mb-3;
}

/* 段落样式 */
.markdown-content :deep(p) {
  @apply mb-4 leading-relaxed text-gray-700 dark:text-gray-300;
}

/* 列表样式 */
.markdown-content :deep(ul) {
  @apply list-disc list-inside space-y-2 my-4 ml-4 text-gray-700 dark:text-gray-300;
}

.markdown-content :deep(ol) {
  @apply list-decimal list-inside space-y-2 my-4 ml-4 text-gray-700 dark:text-gray-300;
}

/* 链接样式 */
.markdown-content :deep(a) {
  @apply text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 underline transition-colors;
}

/* 行内代码样式 */
.markdown-content :deep(code:not(.hljs)) {
  @apply bg-gray-100 dark:bg-gray-800 text-pink-600 dark:text-pink-400 px-2 py-1 rounded text-sm font-mono;
}

/* 引用块样式 */
.markdown-content :deep(blockquote) {
  @apply border-l-4 border-blue-500 dark:border-blue-400 pl-4 py-2 my-6 bg-blue-50 dark:bg-blue-900/20 italic text-gray-700 dark:text-gray-300 rounded-r-lg;
}

/* 强调样式 */
.markdown-content :deep(strong) {
  @apply font-semibold text-gray-900 dark:text-gray-100;
}

.markdown-content :deep(em) {
  @apply italic text-gray-800 dark:text-gray-200;
}

/* 水平线样式 */
.markdown-content :deep(hr) {
  @apply border-t-2 border-gray-200 dark:border-gray-700 my-8;
}

/* 图片样式 */
.markdown-content :deep(img) {
  @apply max-w-full h-auto rounded-lg shadow-lg mx-auto my-6;
}

/* 任务列表样式 */
.markdown-content :deep(input[type="checkbox"]) {
  @apply mr-2 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700;
}
</style>